package com.owen.utils.ftl;


import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.InputStreamSource;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * word模板导出docx文件
 * @author lby
 * @create 2024/1/14 10:01
 */
public class GenerateDocxUtil {

    // 日志
    private static Logger logger = LoggerFactory.getLogger(GenerateDocxUtil.class);

    /**
     * 导出Word文件
     *
     * @param dataMap
     * @param response
     * @throws Exception
     */
    public static InputStreamSource exportDocx(Map<String,Object> dataMap, String templateName, String fileName, HttpServletResponse response) throws Exception {
        // 纠正编码
        response.setCharacterEncoding("UTF-8");
        // ** 初始化配置文件**//*
        Configuration configuration = new Configuration();
        // ** 设置编码 **//*
        configuration.setDefaultEncoding("utf-8");
        // 设置为空不报错
        configuration.setClassicCompatible(true);
        // ** ftl文件的路径**//*
        String fileDirectory = java.net.URLDecoder.decode(GenerateDocxUtil.class.getResource("/templates/ftl").getPath(),"utf-8");
        // 加载模板文件
        configuration.setDirectoryForTemplateLoading(new File(fileDirectory));

        // 加载模板，通过Word转XML文件转换过来的
        Template template = configuration.getTemplate(templateName);
        // 指定输出word文件的路径e
        // 调用工具类WordUtils的createDoc方法生成Word文档
        InputStreamSource file = createDoc(dataMap, template);
        InputStream fin = file.getInputStream();
        ServletOutputStream out;

        response.reset();
        response.setContentType("application/msword");
        // 设置浏览器以下载的方式处理该文件
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName + ".docx", "utf-8"));
        logger.info("文件生成完成.");
        out = response.getOutputStream();
        // 缓冲区
        byte[] buffer = new byte[512];
        int bytesToRead;
        // 通过循环将读入的Word文件的内容输出到浏览器中
        while ((bytesToRead = fin.read(buffer)) != -1) {
            out.write(buffer, 0, bytesToRead);
        }
        fin.close();
        if (out != null) {
            out.close();
        }
        return file;
    }


    private static InputStreamSource createDoc(Map<String, Object> dataMap, Template template)
            throws TemplateException, IOException {
        //生成随机的合同名称
        StringWriter out1 = new StringWriter();
        Writer out = new BufferedWriter(out1, 10240);
        //将数据输出到模板
        template.process(dataMap, out);
        out.close();
        out1.close();
        return new ByteArrayResource(out1.toString().getBytes(StandardCharsets.UTF_8));
    }


}
